_require local "../../../../basis.smi"
(* _require local "../../../libs/ids/main/LocalID.smi" *)
_require local "../../../libs/util/main/TermFormat.smi"

_require "../../../../smlformat-lib.smi"
_require "../../../data/builtin/main/BuiltinPrimitive.ppg.smi"
_require "../../../data/symbols/main/RecordLabel.smi"
(* _require "../../../data/runtimetypes/main/RuntimeTypes.ppg.smi" *)
_require "../../../data/symbols/main/Loc.smi"
_require "../../../compilerIRs/recordcalc/main/RecordCalc.ppg.smi"
_require "../../../compilerIRs/typedlambda/main/TypedLambda.ppg.smi"
_require "../../../data/types/main/Types.ppg.smi"
_require "../../../data/runtimetypes/main/FFIAttributes.ppg.smi"
_require "../../../data/name/main/CodeLabel.smi"

structure BitmapCalc2 =
struct
  type loc = Loc.loc
  type ty = Types.ty
  type varInfo = TypedLambda.varInfo
  type exVarInfo = Types.exVarInfo
  type primInfo = TypedLambda.primInfo
  type btvEnv = Types.btvEnv
  datatype tlint = datatype TypedLambda.tlint
  datatype tlconst = datatype TypedLambda.tlconst
  datatype tlstring = datatype TypedLambda.tlstring
  datatype rcconst = datatype RecordCalc.rcconst

  datatype bcexp =
      BCFOREIGNAPPLY of
      {
        funExp : bcexp,
        attributes : FFIAttributes.attributes,
        argExpList : bcexp list,
        resultTy : ty option,
        loc : loc
      }
    | BCCALLBACKFN of
      {
        attributes : FFIAttributes.attributes,
        argVarList : varInfo list,
        resultTy : ty option,
        bodyExp : bcexp,
        loc: loc
      }
    | BCCONSTANT of {const : rcconst, loc : loc}
    | BCSTRING of {string : tlstring, loc : loc}
    | BCVAR of {varInfo : varInfo, loc : loc}
    | BCEXVAR of {exVarInfo : exVarInfo, loc : loc}
    | BCPRIMAPPLY of
      {
        primInfo : primInfo,
        argExpList : bcexp list,
        instTyList : ty list,
        instTagList : bcexp list,
        instSizeList : bcexp list,
        loc : loc
      }
    | BCAPPM of
      {
        funExp : bcexp,
        argExpList : bcexp list,
        funTy : ty,
        loc : loc
      }
    | BCLET of
      {
        localDecl : bcdecl,
        mainExp : bcexp,
        loc : loc
      }
    | BCRECORD of
      {
        fieldList : {fieldExp : bcexp,
                     fieldTy : ty,
                     fieldLabel : RecordLabel.label,
                     fieldSize : bcexp,
                     fieldTag : bcexp,
                     fieldIndex : bcexp} list,
        recordTy : ty,
        isMutable : bool,
        clearPad : bool,
        allocSizeExp : bcexp,
        bitmaps : {bitmapIndex : bcexp,
                   bitmapExp : bcexp} list,
        loc : loc
      }
    | BCSELECT of
      {
        recordExp : bcexp,
        indexExp : bcexp,
        label : RecordLabel.label,
        recordTy : ty,
        resultTy : ty,
        resultSize : bcexp,
        resultTag : bcexp,
        loc : loc
      }
    | BCMODIFY of
      {
        recordExp : bcexp,
        recordTy : ty,
        indexExp : bcexp,
        label : RecordLabel.label,
        valueExp : bcexp,
        valueTy : ty,
        valueTag : bcexp,
        valueSize : bcexp,
        loc : loc
      }
    | BCRAISE of
      {
        argExp : bcexp,
        resultTy : ty,
        loc : loc
      }
    | BCHANDLE of
      {
        tryExp : bcexp,
        exnVar : varInfo,
        handlerExp : bcexp,
        resultTy : ty,
        loc : loc
      }
    | BCCATCH of
      {
        catchLabel : FunLocalLabel.id,
        argVarList : varInfo list,
        catchExp : bcexp,
        tryExp : bcexp,
        resultTy : ty,
        loc : loc
      }
    | BCTHROW of
      {
        catchLabel : FunLocalLabel.id,
        argExpList : bcexp list,
        resultTy : ty,
        loc : loc
      }
    | BCFNM of
      {
        argVarList : varInfo list,
        bodyExp : bcexp,
        retTy : ty,
        loc : loc
      }
    | BCPOLY of
      {
        btvEnv : btvEnv,
        expTyWithoutTAbs : ty,
        exp : bcexp,
        loc : loc
      }
    | BCTAPP of
      {
        exp : bcexp,
        expTy : ty,
        instTyList : ty list,
        loc : loc
      }
    | BCSWITCH of
      {
        switchExp : bcexp,
        expTy : ty,
        branches : {constant : tlint, branchExp : bcexp} list,
        defaultExp : bcexp,
        resultTy : ty,
        loc : loc
      }
    | BCCAST of
      {
        exp : bcexp,
        expTy : ty,
        targetTy : ty,
        cast : BuiltinPrimitive.cast,
        loc : loc
      }

  and bcdecl =
      BCVAL of
      {
        boundVar : varInfo,
        boundExp : bcexp,
        loc : loc
      }
    | BCVALREC of
      {
        recbindList : {boundVar : varInfo, boundExp: bcexp } list,
        loc : loc
      }
    | BCEXTERNVAR of
      {
        exVarInfo: exVarInfo,
        provider: Types.provider,
        loc: loc
      }
    | BCEXPORTVAR of
      {
        weak : bool,
        exVarInfo : exVarInfo,
        exp : bcexp,
        loc : loc
      }

  val format_bcexp
      : bcexp -> SMLFormat.FormatExpression.expression list
  val format_bcdecl
      : bcdecl -> SMLFormat.FormatExpression.expression list

  val formatWithType_bcexp
      : bcexp -> SMLFormat.FormatExpression.expression list
  val formatWithType_bcdecl
      : bcdecl -> SMLFormat.FormatExpression.expression list

end
